#pragma once

#include "quote_data.h"
#include <unordered_map>
#include <unordered_set>
#include <mutex>
#include <memory>
#include <functional>

namespace yquote {

class QuoteManager {
public:
    using QuoteUpdateCallback = std::function<void(const QuoteData&)>;
    
    QuoteManager();
    ~QuoteManager();
    
    // 更新行情数据
    void updateQuote(const QuoteData& quote);
    
    // 获取指定股票的行情
    QuoteData getQuote(const std::string& symbol) const;
    
    // 获取所有行情数据
    std::vector<QuoteData> getAllQuotes() const;
    
    // 检查股票是否存在
    bool hasSymbol(const std::string& symbol) const;
    
    // 订阅行情更新
    void subscribe(const std::string& client_id, const std::vector<std::string>& symbols);
    
    // 取消订阅
    void unsubscribe(const std::string& client_id, const std::vector<std::string>& symbols);
    
    // 取消客户端的所有订阅
    void unsubscribeAll(const std::string& client_id);
    
    // 获取客户端订阅的股票列表
    std::vector<std::string> getSubscriptions(const std::string& client_id) const;
    
    // 设置行情更新回调函数
    void setQuoteUpdateCallback(QuoteUpdateCallback callback);
    
    // 获取订阅了指定股票的客户端列表
    std::vector<std::string> getSubscribers(const std::string& symbol) const;
    
    // 统计信息
    size_t getQuoteCount() const;
    size_t getSubscriptionCount() const;
    size_t getClientCount() const;
    
private:
    mutable std::mutex quotes_mutex_;
    mutable std::mutex subscriptions_mutex_;
    
    // 行情数据存储 symbol -> QuoteData
    std::unordered_map<std::string, QuoteData> quotes_;
    
    // 订阅关系存储 client_id -> set<symbol>
    std::unordered_map<std::string, std::unordered_set<std::string>> client_subscriptions_;
    
    // 反向索引 symbol -> set<client_id>
    std::unordered_map<std::string, std::unordered_set<std::string>> symbol_subscribers_;
    
    // 行情更新回调
    QuoteUpdateCallback quote_update_callback_;
    
    // 内部方法
    void notifySubscribers(const QuoteData& quote);
    void addSubscription(const std::string& client_id, const std::string& symbol);
    void removeSubscription(const std::string& client_id, const std::string& symbol);
};

} // namespace yquote 